// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Trace.cs" company="AzureContrib (Open source library http://azurecontrib.codeplex.com)">
//   Microsoft Public License (Ms-PL)
// </copyright>
// <summary>
//   Exception for errors when handling Windows Azure Cloud Drives.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;

using AzureContrib.WindowsAzure.Properties;

using SD = System.Diagnostics;

namespace AzureContrib.WindowsAzure.Diagnostics
{
	/// <summary>
	/// A trace Message following the <see cref="ITrace"/>
	/// </summary>
	public class Trace : TraceBase, ITrace
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="Trace"/> class. 
		/// </summary>
		/// <param name="toTraceFor">The type we are logging for.</param>
		/// <param name="traceSwitchProvider">The <see cref="ITraceSwitchProvider"/>.</param>
		public Trace(Type toTraceFor, ITraceSwitchProvider traceSwitchProvider)
			: base(toTraceFor, traceSwitchProvider)
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="Trace"/> class. 
		/// </summary>
		/// <param name="switch">The identifying switch used to pinpoint the trace.</param>
		/// <param name="traceSwitchProvider">The <see cref="ITraceSwitchProvider"/>.</param>
		public Trace(string @switch, ITraceSwitchProvider traceSwitchProvider)
			: base(@switch, traceSwitchProvider)
		{
		}

		#region Old School

		/// <summary>
		/// Maps to <see cref="SD.Trace.TraceInformation(string)"/>
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		public void TraceInformation(string message)
		{
			Information(message);
		}

		/// <summary>
		/// Maps to <see cref="SD.Trace.TraceInformation(string,object[])"/>
		/// </summary>
		/// <param name="format">
		/// The format.
		/// </param>
		/// <param name="args">
		/// The args.
		/// </param>
		// ReSharper disable MethodOverloadWithOptionalParameter
		public void TraceInformation(string format, params object[] args)
		// ReSharper restore MethodOverloadWithOptionalParameter
		{
			Information(() => string.Format(CultureInfo.InvariantCulture, format, args));
		}

		/// <summary>
		/// Maps to <see cref="SD.Trace.TraceWarning(string)"/>
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		public void TraceWarning(string message)
		{
			Warning(message);
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.TraceWarning(string,object[])"/>
		/// </summary>
		/// <param name="format">
		/// The format.
		/// </param>
		/// <param name="args">
		/// The args.
		/// </param>
		// ReSharper disable MethodOverloadWithOptionalParameter
		public void TraceWarning(string format, params object[] args)
		// ReSharper restore MethodOverloadWithOptionalParameter
		{
			Warning(() => string.Format(CultureInfo.InvariantCulture, format, args));
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.TraceError(string)"/>
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		public void TraceError(string message)
		{
			Error(message);
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.TraceError(string,object[])"/>
		/// </summary>
		/// <param name="format">
		/// The format.
		/// </param>
		/// <param name="args">
		/// The args.
		/// </param>
		// ReSharper disable MethodOverloadWithOptionalParameter
		public void TraceError(string format, params object[] args)
		// ReSharper restore MethodOverloadWithOptionalParameter
		{
			Error(() => string.Format(CultureInfo.InvariantCulture, format, args));
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.Write(object)"/>
		/// </summary>
		/// <param name="value">
		/// The value.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc.", false)]
		public void Write(object value)
		{
			value = value ?? Strings.Null;
			var traceMessageBase = TraceMessageFactory.Create(LogLevel.Undefined, Switch, string.Format(CultureInfo.CurrentCulture, "{0}", value));
			SD.Trace.Write(traceMessageBase);
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.Write(string)"/>
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc.", false)]
		public void Write(string message)
		{
			var traceMessageBase = TraceMessageFactory.Create(LogLevel.Undefined, Switch, message);
			SD.Trace.Write(traceMessageBase);
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.Write(object,string)"/>
		/// </summary>
		/// <param name="value">The value.</param>
		/// <param name="category">The category.</param>
		/// <remarks>This is not a recommended usage. Use any method named by a <see cref="LogLevel"/> value, i.e. <see cref="ITrace.Information(string)"/>.</remarks>
		/// <remarks>If you do decide to use this method please consider using a <paramref name="category"/> based on a <see cref="LogLevel"/> value.</remarks>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc. Use of 'category' is ambiguous.", false)]
		public void Write(object value, string category)
		{
		}

		/// <summary>
		/// Calls <see cref="SD.Trace"/>
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="category">
		/// The category.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc. Use of 'category' is ambiguous.", false)]
		public void Write(string message, string category)
		{
			WriteLine(message, category);
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.WriteIf(bool,string)"/>
		/// </summary>
		/// <param name="condition">
		/// The condition.
		/// </param>
		/// <param name="message">
		/// The Message.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc.", false)]
		public void WriteIf(bool condition, string message)
		{
			if (!condition)
			{
				return;
			}

			WriteLine(message);
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.WriteIf(bool,object,string)"/>
		/// </summary>
		/// <param name="condition">
		/// The condition.
		/// </param>
		/// <param name="value">
		/// The value.
		/// </param>
		/// <param name="category">
		/// The category.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc. Use of 'category' is ambiguous.", false)]
		public void WriteIf(bool condition, object value, string category)
		{
			if (!condition)
			{
				return;
			}

			WriteLine(value, category);
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.WriteIf(bool,string,string)"/>
		/// </summary>
		/// <param name="condition">
		/// The condition.
		/// </param>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="category">
		/// The category.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc. Use of 'category' is ambiguous.", false)]
		public void WriteIf(bool condition, string message, string category)
		{
			if (!condition)
			{
				return;
			}

			WriteLine(message, category);
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.WriteLine(object)"/>
		/// </summary>
		/// <param name="value">
		/// The value.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc.", false)]
		public void WriteLine(object value)
		{
			TraceIfLogLevelIsUndefined(() => string.Format(CultureInfo.CurrentCulture, "{0}", value));
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.WriteLine(string)"/>
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc.", false)]
		public void WriteLine(string message)
		{
			TraceIfLogLevelIsUndefined(() => message);
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.WriteLine(object,string)"/>
		/// </summary>
		/// <param name="value">
		/// The value.
		/// </param>
		/// <param name="category">
		/// The category.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc. Use of 'category' is ambiguous.", false)]
		public void WriteLine(object value, string category)
		{
			WriteLine(string.Format(CultureInfo.CurrentCulture, "{0}", value), category);
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.WriteLine(string,string)"/>
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="category">
		/// The category.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc. Use of 'category' is ambiguous.", false)]
		public void WriteLine(string message, string category)
		{
			WriteLineIf(true, message, category);
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.WriteLineIf(bool,object)"/>
		/// </summary>
		/// <param name="condition">
		/// The condition.
		/// </param>
		/// <param name="value">
		/// The value.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc.", false)]
		public void WriteLineIf(bool condition, object value)
		{
			if (!condition)
			{
				return;
			}

			TraceIfLogLevelIsUndefined(() => value.ToString());
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.WriteLineIf(bool,string)"/>
		/// </summary>
		/// <param name="condition">
		/// The condition.
		/// </param>
		/// <param name="message">
		/// The Message.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc.", false)]
		public void WriteLineIf(bool condition, string message)
		{
			if (!condition)
			{
				return;
			}

			TraceIfLogLevelIsUndefined(() => message);
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.WriteLineIf(bool,object,string)"/>
		/// </summary>
		/// <param name="condition">
		/// The condition.
		/// </param>
		/// <param name="value">
		/// The value.
		/// </param>
		/// <param name="category">
		/// The category.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc. Use of 'category' is ambiguous.", false)]
		public void WriteLineIf(bool condition, object value, string category)
		{
			if (!condition)
			{
				return;
			}

			LogLevel logLevel;
			if (TryParse(category, out logLevel))
			{
				TraceMessageBase traceMessage = null;

				switch (logLevel)
				{
					case LogLevel.Verbose:
						if (!TraceSwitchProvider.Enabled(LogLevel.Verbose, this))
						{
							return;
						}

						break;
					case LogLevel.Information:
						if (!TraceSwitchProvider.Enabled(LogLevel.Information, this))
						{
							return;
						}

						break;
					case LogLevel.Warning:
						if (!TraceSwitchProvider.Enabled(LogLevel.Warning, this))
						{
							return;
						}

						break;
					case LogLevel.Error:
						if (!TraceSwitchProvider.Enabled(LogLevel.Error, this))
						{
							return;
						}

						break;
					case LogLevel.Critical:
						if (!TraceSwitchProvider.Enabled(LogLevel.Critical, this))
						{
							return;
						}

						break;
					case LogLevel.Undefined:
						break;
					case LogLevel.Off:
						return;
				}

				traceMessage = TraceMessageFactory.Create(logLevel, Switch, string.Format(CultureInfo.CurrentCulture, "{0}", value));
				SD.Trace.WriteLine(traceMessage /* Calls implicit cast to string. */, category);
				return;
			}

			TraceIfLogLevelIsUndefined(() => string.Format(CultureInfo.CurrentCulture, "{0}", value), category);
		}

		/// <summary>
		/// Calls <see cref="SD.Trace.WriteLineIf(bool,string,string)"/>
		/// </summary>
		/// <param name="condition">
		/// The condition.
		/// </param>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="category">
		/// The category.
		/// </param>
		[Obsolete("Recommended usage is to use any method that clearly defines a log level like Information, Error, etc. Use of 'category' is ambiguous.", false)]
		public void WriteLineIf(bool condition, string message, string category)
		{
			if (!condition)
			{
				return;
			}

			LogLevel logLevel;
			if (TryParse(category, out logLevel))
			{
				switch (logLevel)
				{
					case LogLevel.Verbose:
						Verbose(message);
						return;
					case LogLevel.Information:
						Information(message);
						return;
					case LogLevel.Warning:
						Warning(message);
						return;
					case LogLevel.Error:
						Error(message);
						return;
					case LogLevel.Critical:
						Critical(message);
						return;
					case LogLevel.Undefined:
						TraceIfLogLevelIsUndefined(() => message);
						return;
					default: // LogLevel.Off
						return;
				}
			}

			TraceIfLogLevelIsUndefined(() => message, category);
		}

		#endregion

		#region Verbose

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "AzureContrib.WindowsAzure.Core.Assumes.NotNull handles null checking.")]
		public void Verbose(Func<string> message)
		{
			Assumes.NotNull(message, "Message");
			TraceIfLogLevelIsVerbose(message);
		}

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		public void Verbose(string message)
		{
			TraceIfLogLevelIsVerbose(() => message);
		}

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg">The type of the argument.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg">
		/// The arg.
		/// </param>
		public void Verbose<TArg>(string message, TArg arg)
		{
			TraceIfLogLevelIsVerbose(() => string.Format(CultureInfo.InvariantCulture, message, arg));
		}

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg">The type of argument.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg">
		/// The arg.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Verbose<TArg>(string message, TArg arg, IFormatProvider provider)
		{
			TraceIfLogLevelIsVerbose(() => string.Format(provider, message, arg));
		}

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of argument 1.</typeparam>
		/// <typeparam name="TArg2">The type of argument 2.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		public void Verbose<TArg1, TArg2>(string message, TArg1 arg1, TArg2 arg2)
		{
			TraceIfLogLevelIsVerbose(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2));
		}

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Verbose<TArg1, TArg2>(string message, TArg1 arg1, TArg2 arg2, IFormatProvider provider)
		{
			TraceIfLogLevelIsVerbose(() => string.Format(provider, message, arg1, arg2));
		}

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		public void Verbose<TArg1, TArg2, TArg3>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3)
		{
			TraceIfLogLevelIsVerbose(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3));
		}

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Verbose<TArg1, TArg2, TArg3>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, IFormatProvider provider)
		{
			TraceIfLogLevelIsVerbose(() => string.Format(provider, message, arg1, arg2, arg3));
		}

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		public void Verbose<TArg1, TArg2, TArg3, TArg4>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
		{
			TraceIfLogLevelIsVerbose(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4));
		}

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Verbose<TArg1, TArg2, TArg3, TArg4>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, IFormatProvider provider)
		{
			TraceIfLogLevelIsVerbose(() => string.Format(provider, message, arg1, arg2, arg3, arg4));
		}

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		public void Verbose<TArg1, TArg2, TArg3, TArg4, TArg5>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
		{
			TraceIfLogLevelIsVerbose(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4, arg5));
		}

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1618:GenericTypeParametersMustBeDocumented",
			Justification = "Reviewed. Suppression is OK here.")]
		public void Verbose<TArg1, TArg2, TArg3, TArg4, TArg5>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, IFormatProvider provider)
		{
			TraceIfLogLevelIsVerbose(() => string.Format(provider, message, arg1, arg2, arg3, arg4, arg5));
		}

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <typeparam name="TArg6">The type of arg 6.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		/// <param name="arg6">
		/// The arg 6.
		/// </param>
		public void Verbose<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6)
		{
			TraceIfLogLevelIsVerbose(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4, arg5, arg6));
		}

		/// <summary>
		/// Trace a Message as Verbose. Only trace if <see cref="ITraceControls.VerboseEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <typeparam name="TArg6">The type of arg 6.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		/// <param name="arg6">
		/// The arg 6.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Verbose<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, IFormatProvider provider)
		{
			TraceIfLogLevelIsVerbose(() => string.Format(provider, message, arg1, arg2, arg3, arg4, arg5, arg6));
		}

		#endregion Verbose

		#region Information

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "AzureContrib.WindowsAzure.Core.Assumes.NotNull handles null checking.")]
		public void Information(Func<string> message)
		{
			Assumes.NotNull(message, "Message");
			TraceIfLogLevelIsInformation(message);
		}

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		public void Information(string message)
		{
			TraceIfLogLevelIsInformation(() => message);
		}

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg">The type of arg.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg">
		/// The arg.
		/// </param>
		public void Information<TArg>(string message, TArg arg)
		{
			TraceIfLogLevelIsInformation(() => string.Format(CultureInfo.InvariantCulture, message, arg));
		}

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg">The type of arg.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg">
		/// The arg.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Information<TArg>(string message, TArg arg, IFormatProvider provider)
		{
			TraceIfLogLevelIsInformation(() => string.Format(provider, message, arg));
		}

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		public void Information<TArg1, TArg2>(string message, TArg1 arg1, TArg2 arg2)
		{
			TraceIfLogLevelIsInformation(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2));
		}

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Information<TArg1, TArg2>(string message, TArg1 arg1, TArg2 arg2, IFormatProvider provider)
		{
			TraceIfLogLevelIsInformation(() => string.Format(provider, message, arg1, arg2));
		}

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		public void Information<TArg1, TArg2, TArg3>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3)
		{
			TraceIfLogLevelIsInformation(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3));
		}

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Information<TArg1, TArg2, TArg3>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, IFormatProvider provider)
		{
			TraceIfLogLevelIsInformation(() => string.Format(provider, message, arg1, arg2, arg3));
		}

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		public void Information<TArg1, TArg2, TArg3, TArg4>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
		{
			TraceIfLogLevelIsInformation(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4));
		}

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Information<TArg1, TArg2, TArg3, TArg4>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, IFormatProvider provider)
		{
			TraceIfLogLevelIsInformation(() => string.Format(provider, message, arg1, arg2, arg3, arg4));
		}

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		public void Information<TArg1, TArg2, TArg3, TArg4, TArg5>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
		{
			TraceIfLogLevelIsInformation(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4, arg5));
		}

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Information<TArg1, TArg2, TArg3, TArg4, TArg5>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, IFormatProvider provider)
		{
			TraceIfLogLevelIsInformation(() => string.Format(provider, message, arg1, arg2, arg3, arg4, arg5));
		}

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <typeparam name="TArg6">The type of arg 6.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		/// <param name="arg6">
		/// The arg 6.
		/// </param>
		public void Information<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6)
		{
			TraceIfLogLevelIsInformation(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4, arg5, arg6));
		}

		/// <summary>
		/// Trace a Message as Information. Only trace if <see cref="ITraceControls.InformationEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <typeparam name="TArg6">The type of arg 6.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		/// <param name="arg6">
		/// The arg 6.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Information<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, IFormatProvider provider)
		{
			TraceIfLogLevelIsInformation(() => string.Format(provider, message, arg1, arg2, arg3, arg4, arg5, arg6));
		}

		#endregion Information

		#region Warning

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "AzureContrib.WindowsAzure.Core.Assumes.NotNull handles null checking.")]
		public void Warning(Func<string> message)
		{
			Assumes.NotNull(message, "Message");
			TraceIfLogLevelIsWarning(message);
		}

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		public void Warning(string message)
		{
			TraceIfLogLevelIsWarning(() => message);
		}

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg">The type of arg.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg">
		/// The arg.
		/// </param>
		public void Warning<TArg>(string message, TArg arg)
		{
			TraceIfLogLevelIsWarning(() => string.Format(CultureInfo.InvariantCulture, message, arg));
		}

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg">The type of arg.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg">
		/// The arg.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Warning<TArg>(string message, TArg arg, IFormatProvider provider)
		{
			TraceIfLogLevelIsWarning(() => string.Format(provider, message, arg));
		}

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		public void Warning<TArg1, TArg2>(string message, TArg1 arg1, TArg2 arg2)
		{
			TraceIfLogLevelIsWarning(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2));
		}

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Warning<TArg1, TArg2>(string message, TArg1 arg1, TArg2 arg2, IFormatProvider provider)
		{
			TraceIfLogLevelIsWarning(() => string.Format(provider, message, arg1, arg2));
		}

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		public void Warning<TArg1, TArg2, TArg3>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3)
		{
			TraceIfLogLevelIsWarning(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3));
		}

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Warning<TArg1, TArg2, TArg3>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, IFormatProvider provider)
		{
			TraceIfLogLevelIsWarning(() => string.Format(provider, message, arg1, arg2, arg3));
		}

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		public void Warning<TArg1, TArg2, TArg3, TArg4>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
		{
			TraceIfLogLevelIsWarning(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4));
		}

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Warning<TArg1, TArg2, TArg3, TArg4>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, IFormatProvider provider)
		{
			TraceIfLogLevelIsWarning(() => string.Format(provider, message, arg1, arg2, arg3, arg4));
		}

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		public void Warning<TArg1, TArg2, TArg3, TArg4, TArg5>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
		{
			TraceIfLogLevelIsWarning(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4, arg5));
		}

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Warning<TArg1, TArg2, TArg3, TArg4, TArg5>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, IFormatProvider provider)
		{
			TraceIfLogLevelIsWarning(() => string.Format(provider, message, arg1, arg2, arg3, arg4, arg5));
		}

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <typeparam name="TArg6">The type of arg 6.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		/// <param name="arg6">
		/// The arg 6.
		/// </param>
		public void Warning<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6)
		{
			TraceIfLogLevelIsWarning(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4, arg5, arg6));
		}

		/// <summary>
		/// Trace a Message as Warning. Only trace if <see cref="ITraceControls.WarningEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <typeparam name="TArg6">The type of arg 6.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		/// <param name="arg6">
		/// The arg 6.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Warning<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, IFormatProvider provider)
		{
			TraceIfLogLevelIsWarning(() => string.Format(provider, message, arg1, arg2, arg3, arg4, arg5, arg6));
		}

		#endregion Warning

		#region Error

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "AzureContrib.WindowsAzure.Core.Assumes.NotNull handles null checking.")]
		public void Error(Func<string> message)
		{
			Assumes.NotNull(message, "Message");
			TraceIfLogLevelIsError(message);
		}

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		public void Error(string message)
		{
			TraceIfLogLevelIsError(() => message);
		}

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg">The type of arg.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg">
		/// The arg.
		/// </param>
		public void Error<TArg>(string message, TArg arg)
		{
			TraceIfLogLevelIsError(() => string.Format(CultureInfo.InvariantCulture, message, arg));
		}

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg">The type of arg.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg">
		/// The arg.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Error<TArg>(string message, TArg arg, IFormatProvider provider)
		{
			TraceIfLogLevelIsError(() => string.Format(provider, message, arg));
		}

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		public void Error<TArg1, TArg2>(string message, TArg1 arg1, TArg2 arg2)
		{
			TraceIfLogLevelIsError(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2));
		}

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Error<TArg1, TArg2>(string message, TArg1 arg1, TArg2 arg2, IFormatProvider provider)
		{
			TraceIfLogLevelIsError(() => string.Format(provider, message, arg1, arg2));
		}

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		public void Error<TArg1, TArg2, TArg3>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3)
		{
			TraceIfLogLevelIsError(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3));
		}

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Error<TArg1, TArg2, TArg3>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, IFormatProvider provider)
		{
			TraceIfLogLevelIsError(() => string.Format(provider, message, arg1, arg2, arg3));
		}

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		public void Error<TArg1, TArg2, TArg3, TArg4>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
		{
			TraceIfLogLevelIsError(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4));
		}

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Error<TArg1, TArg2, TArg3, TArg4>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, IFormatProvider provider)
		{
			TraceIfLogLevelIsError(() => string.Format(provider, message, arg1, arg2, arg3, arg4));
		}

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		public void Error<TArg1, TArg2, TArg3, TArg4, TArg5>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
		{
			TraceIfLogLevelIsError(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4, arg5));
		}

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Error<TArg1, TArg2, TArg3, TArg4, TArg5>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, IFormatProvider provider)
		{
			TraceIfLogLevelIsError(() => string.Format(provider, message, arg1, arg2, arg3, arg4, arg5));
		}

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <typeparam name="TArg6">The type of arg 6.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		/// <param name="arg6">
		/// The arg 6.
		/// </param>
		public void Error<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6)
		{
			TraceIfLogLevelIsError(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4, arg5, arg6));
		}

		/// <summary>
		/// Trace a Message as Error. Only trace if <see cref="ITraceControls.ErrorEnabled"/>.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <typeparam name="TArg6">The type of arg 6.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		/// <param name="arg5">
		/// The arg 5.
		/// </param>
		/// <param name="arg6">
		/// The arg 6.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Error<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, IFormatProvider provider)
		{
			TraceIfLogLevelIsError(() => string.Format(provider, message, arg1, arg2, arg3, arg4, arg5, arg6));
		}

		#endregion

		#region Critical

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "AzureContrib.WindowsAzure.Core.Assumes.NotNull handles null checking.")]
		public void Critical(Func<string> message)
		{
			Assumes.NotNull(message, "Message");
			TraceIfLogLevelIsCritical(message);
		}

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <param name="message">
		/// The Message.
		/// </param>
		public void Critical(string message)
		{
			TraceIfLogLevelIsCritical(() => message);
		}

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <typeparam name="TArg">The type of arg.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg">
		/// The arg.
		/// </param>
		public void Critical<TArg>(string message, TArg arg)
		{
			TraceIfLogLevelIsCritical(() => string.Format(CultureInfo.InvariantCulture, message, arg));
		}

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <typeparam name="TArg">The type of arg.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg">
		/// The arg.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Critical<TArg>(string message, TArg arg, IFormatProvider provider)
		{
			TraceIfLogLevelIsCritical(() => string.Format(provider, message, arg));
		}

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		public void Critical<TArg1, TArg2>(string message, TArg1 arg1, TArg2 arg2)
		{
			TraceIfLogLevelIsCritical(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2));
		}

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Critical<TArg1, TArg2>(string message, TArg1 arg1, TArg2 arg2, IFormatProvider provider)
		{
			TraceIfLogLevelIsCritical(() => string.Format(provider, message, arg1, arg2));
		}

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		public void Critical<TArg1, TArg2, TArg3>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3)
		{
			TraceIfLogLevelIsCritical(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3));
		}

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="provider">
		/// The provider.
		/// </param>
		public void Critical<TArg1, TArg2, TArg3>(
			string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, IFormatProvider provider)
		{
			TraceIfLogLevelIsCritical(() => string.Format(provider, message, arg1, arg2, arg3));
		}

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <param name="message">
		/// The Message.
		/// </param>
		/// <param name="arg1">
		/// The arg 1.
		/// </param>
		/// <param name="arg2">
		/// The arg 2.
		/// </param>
		/// <param name="arg3">
		/// The arg 3.
		/// </param>
		/// <param name="arg4">
		/// The arg 4.
		/// </param>
		public void Critical<TArg1, TArg2, TArg3, TArg4>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
		{
			TraceIfLogLevelIsCritical(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4));
		}

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <param name="message">The Message.</param>
		/// <param name="arg1">The arg 1.</param>
		/// <param name="arg2">The arg 2.</param>
		/// <param name="arg3">The arg 3.</param>
		/// <param name="arg4">The arg 4.</param>
		/// <param name="provider">The provider.</param>
		public void Critical<TArg1, TArg2, TArg3, TArg4>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, IFormatProvider provider)
		{
			TraceIfLogLevelIsCritical(() => string.Format(provider, message, arg1, arg2, arg3, arg4));
		}

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <param name="message">The Message.</param>
		/// <param name="arg1">The arg 1.</param>
		/// <param name="arg2">The arg 2.</param>
		/// <param name="arg3">The arg 3.</param>
		/// <param name="arg4">The arg 4.</param>
		/// <param name="arg5">The arg 5.</param>
		public void Critical<TArg1, TArg2, TArg3, TArg4, TArg5>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
		{
			TraceIfLogLevelIsCritical(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4, arg5));
		}

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <param name="message">The Message.</param>
		/// <param name="arg1">The arg 1.</param>
		/// <param name="arg2">The arg 2.</param>
		/// <param name="arg3">The arg 3.</param>
		/// <param name="arg4">The arg 4.</param>
		/// <param name="arg5">The arg 5.</param>
		/// <param name="provider">The provider.</param>
		public void Critical<TArg1, TArg2, TArg3, TArg4, TArg5>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, IFormatProvider provider)
		{
			TraceIfLogLevelIsCritical(() => string.Format(provider, message, arg1, arg2, arg3, arg4, arg5));
		}

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <typeparam name="TArg6">The type of arg 6.</typeparam>
		/// <param name="message">The Message.</param>
		/// <param name="arg1">The arg 1.</param>
		/// <param name="arg2">The arg 2.</param>
		/// <param name="arg3">The arg 3.</param>
		/// <param name="arg4">The arg 4.</param>
		/// <param name="arg5">The arg 5.</param>
		/// <param name="arg6">The arg 6.</param>
		public void Critical<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6)
		{
			TraceIfLogLevelIsCritical(() => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3, arg4, arg5, arg6));
		}

		/// <summary>
		/// Trace a Message as Critical.
		/// </summary>
		/// <typeparam name="TArg1">The type of arg 1.</typeparam>
		/// <typeparam name="TArg2">The type of arg 2.</typeparam>
		/// <typeparam name="TArg3">The type of arg 3.</typeparam>
		/// <typeparam name="TArg4">The type of arg 4.</typeparam>
		/// <typeparam name="TArg5">The type of arg 5.</typeparam>
		/// <typeparam name="TArg6">The type of arg 6.</typeparam>
		/// <param name="message">The Message.</param>
		/// <param name="arg1">The arg 1.</param>
		/// <param name="arg2">The arg 2.</param>
		/// <param name="arg3">The arg 3.</param>
		/// <param name="arg4">The arg 4.</param>
		/// <param name="arg5">The arg 5.</param>
		/// <param name="arg6">The arg 6.</param>
		/// <param name="provider">The provider.</param>
		public void Critical<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(string message, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, IFormatProvider provider)
		{
			TraceIfLogLevelIsCritical(() => string.Format(provider, message, arg1, arg2, arg3, arg4, arg5, arg6));
		}

		#endregion Critical

		/// <summary>
		/// Will be <see cref="LogLevel.Undefined"/> if the category is not transformable to a LogLevel.
		/// </summary>
		/// <param name="category">The category to convert to a <see cref="LogLevel"/>.</param>
		/// <param name="logLevel">The parsed <see cref="LogLevel"/> value.</param>
		/// <returns>The <see cref="LogLevel"/> parsed from the <paramref name="category"/> or <see cref="LogLevel.Undefined"/>.</returns>
		private static bool TryParse(string category, out LogLevel logLevel)
		{
			logLevel = LogLevel.Undefined;

			if (!string.IsNullOrEmpty(category) && !category.TryParseLogLevel(out logLevel))
			{
				logLevel = LogLevel.Undefined;
				return false;
			}

			return true;
		}

		/// <summary>
		/// Perform logging if it is enabled at <see cref="LogLevel.Verbose"/> for the <see cref="ITraceSwitchable.Switch"/> in this instance using <paramref name="message"/>.
		/// </summary>
		/// <param name="message">The message function to call to actually generate a formatted <see cref="string"/> message.</param>
		private void TraceIfLogLevelIsVerbose(Func<string> message)
		{
			if (TraceSwitchProvider.Enabled(LogLevel.Verbose, this))
			{
				TraceThis(message, LogLevelCategories.Verbose);
			}
		}

		/// <summary>
		/// Perform logging if it is enabled at <see cref="LogLevel.Information"/> for the <see cref="ITraceSwitchable.Switch"/> in this instance using <paramref name="message"/>.
		/// </summary>
		/// <param name="message">The message function to call to actually generate a formatted <see cref="string"/> message.</param>
		private void TraceIfLogLevelIsInformation(Func<string> message)
		{
			if (TraceSwitchProvider.Enabled(LogLevel.Information, this))
			{
				TraceThis(message, LogLevelCategories.Information);
			}
		}

		/// <summary>
		/// Perform logging if it is enabled at <see cref="LogLevel.Warning"/> for the <see cref="ITraceSwitchable.Switch"/> in this instance using <paramref name="message"/>.
		/// </summary>
		/// <param name="message">The message function to call to actually generate a formatted <see cref="string"/> message.</param>
		private void TraceIfLogLevelIsWarning(Func<string> message)
		{
			if (TraceSwitchProvider.Enabled(LogLevel.Warning, this))
			{
				TraceThis(message, LogLevelCategories.Warning);
			}
		}

		/// <summary>
		/// Perform logging if it is enabled at <see cref="LogLevel.Error"/> for the <see cref="ITraceSwitchable.Switch"/> in this instance using <paramref name="message"/>.
		/// </summary>
		/// <param name="message">The message function to call to actually generate a formatted <see cref="string"/> message.</param>
		private void TraceIfLogLevelIsError(Func<string> message)
		{
			if (TraceSwitchProvider.Enabled(LogLevel.Error, this))
			{
				TraceThis(message, LogLevelCategories.Error);
			}
		}

		/// <summary>
		/// Perform logging if it is enabled at <see cref="LogLevel.Critical"/> for the <see cref="ITraceSwitchable.Switch"/> in this instance using <paramref name="message"/>.
		/// </summary>
		/// <param name="message">The message function to call to actually generate a formatted <see cref="string"/> message.</param>
		private void TraceIfLogLevelIsCritical(Func<string> message)
		{
			if (TraceSwitchProvider.Enabled(LogLevel.Critical, this))
			{
				TraceThis(message, LogLevelCategories.Critical);
			}
		}

		/// <summary>
		/// Perform logging if it is enabled at <see cref="LogLevel.Undefined"/> for the <see cref="ITraceSwitchable.Switch"/> in this instance using <paramref name="message"/>.
		/// </summary>
		/// <param name="message">The message function to call to actually generate a formatted <see cref="string"/> message.</param>
		private void TraceIfLogLevelIsUndefined(Func<string> message)
		{
			TraceIfLogLevelIsUndefined(message, LogLevel.Undefined.ToString());
		}

		/// <summary>
		/// Perform logging if it is enabled at <see cref="LogLevel.Undefined"/> for the <see cref="ITraceSwitchable.Switch"/> in this instance using <paramref name="message"/>.
		/// </summary>
		/// <param name="message">The message function to call to actually generate a formatted <see cref="string"/> message.</param>
		/// <param name="category">The category to trace to.</param>
		private void TraceIfLogLevelIsUndefined(Func<string> message, string category)
		{
			if (!TraceSwitchProvider.Enabled(LogLevel.Undefined, this))
			{
				return;
			}

			TraceMessageBase traceMessage = TraceMessageFactory.Create(LogLevelCategories.Undefined, Switch, message());
			SD.Trace.WriteLine(traceMessage /* Calls implicit cast to string. */, category);
		}

		/// <summary>
		/// Trace the <paramref name="message"/> at the level <paramref name="levelName"/>.
		/// </summary>
		/// <param name="message">The function that will generate the message.</param>
		/// <param name="levelName">The level as a <see cref="string"/>.</param>
		private void TraceThis(Func<string> message, string levelName)
		{
			TraceMessageBase traceMessage = TraceMessageFactory.Create(levelName, Switch, message());
			SD.Trace.WriteLine(traceMessage /* Calls implicit cast to string. */, levelName);
		}
	}
}